package utility

import (
	"crypto/md5"
	"crypto/rand"
	"crypto/sha1"
	"encoding/base64"
	"encoding/hex"
	"fmt"
	"io"
	"strings"
	"time"
)

func First(args ...interface{}) interface{} {
	return args[0]
}

const (
	base64Table = "123QRSTUabcdVWXYZHijKLAWDCABDstEFGuvwxyzGHIJklmnopqr234560178912"
	cipherstr   = "67FFHVVHHHBGUIYG"
)

var coder = base64.NewEncoding(base64Table)

func base64Encode(src []byte) []byte {
	return []byte(coder.EncodeToString(src))
}
func base64Decode(src []byte) ([]byte, error) {
	return coder.DecodeString(string(src))
}
func EncryptStr(str string) string {
	return str + "-" + GetSha1String(str)
}

func DecryptStr(str string) string {
	if strings.Contains(str, "-") {
		var attr = strings.Split(str, "-")
		if attr[1] == GetSha1String(attr[0]) {
			return attr[0]
		}
	}
	return ""
}

func DecryptStrAfterSuffix(str string) string {
	if strings.Contains(str, "-") {
		var attr = strings.Split(str, "-")
		if strings.HasSuffix(GetSha1String(attr[0]), attr[1]) {
			return attr[0]
		}
	}
	return ""
}

func Pick(index int, args ...interface{}) interface{} {
	return args[index]
}

func GetMd5String(s string) string {
	h := md5.New()
	h.Write([]byte(s))
	return hex.EncodeToString(h.Sum(nil))
}
func GetSha1String(s string) string {
	h := sha1.New()
	s = s + "dfgegnnkqewr3242"
	h.Write([]byte(s))
	return hex.EncodeToString(h.Sum(nil))
}

//使用 URL 兼容的 base64 格式进行编解码。
func Base64UrlEncode(src string) string {
	return base64.URLEncoding.EncodeToString([]byte(src))
}
func Base64UrlDecode(src string) (string, error) {
	uDec, err := base64.URLEncoding.DecodeString(src)
	ret := ""
	if err == nil {
		ret = string(uDec)
	}
	return ret, err
}

func CipherEncode(sourceText string) string {
	h := md5.New()
	h.Write([]byte(cipherstr))
	cipherHash := fmt.Sprintf("%x", h.Sum(nil))
	h.Reset()
	inputData := []byte(sourceText)
	loopCount := len(inputData)
	outData := make([]byte, loopCount)
	for i := 0; i < loopCount; i++ {
		outData[i] = inputData[i] ^ cipherHash[i%32]
	}
	return fmt.Sprintf("%s", outData)
}
func Base64CipEncode(sourceText string) string {
	if sourceText == "" {
		return ""
	}

	h := md5.New()
	h.Write([]byte(time.Now().Format("2006-01-02 15:04:05")))
	noise := fmt.Sprintf("%x", h.Sum(nil))
	h.Reset()
	inputData := []byte(sourceText)
	loopCount := len(inputData)
	outData := make([]byte, loopCount*2)

	for i, j := 0, 0; i < loopCount; i, j = i+1, j+1 {
		outData[j] = noise[i%32]
		j++
		outData[j] = inputData[i] ^ noise[i%32]
	}

	return base64.StdEncoding.EncodeToString([]byte(CipherEncode(fmt.Sprintf("%s", outData))))
}
func Base64CipDecode(sourceText string) string {
	if sourceText == "" {
		return ""
	}
	buf, err := base64.StdEncoding.DecodeString(sourceText)
	if err != nil {
		//LogWarning("Base64", fmt.Sprintf("Decode(%q) failed: %v", sourceText, err))
		return ""
	}
	inputData := []byte(CipherEncode(fmt.Sprintf("%s", buf)))
	loopCount := len(inputData)
	outData := make([]byte, loopCount)
	for i, j := 0, 0; i < loopCount; i, j = i+2, j+1 {
		outData[j] = inputData[i] ^ inputData[i+1]
	}
	return fmt.Sprintf("%s", outData[0:16])
}

func GetGuid(len int) string {
	if len > 64 {
		return ""
	}
	b := make([]byte, 64)
	if _, err := io.ReadFull(rand.Reader, b); err != nil {
		return ""
	}
	return base64.URLEncoding.EncodeToString(b)[0:len]
}

func SubString(str string, begin, length int) (substr string) {
	// 将字符串的转换成[]rune
	rs := []rune(str)
	lth := len(rs)

	// 简单的越界判断
	if begin < 0 {
		begin = 0
	}
	if begin >= lth {
		begin = lth
	}
	end := begin + length
	if end > lth {
		end = lth
	}

	// 返回子串
	return string(rs[begin:end])
}
